/* 
 * File:   common_FirmaDigital.h
 * Author: gabilan
 *
 * Created on 12 de junio de 2013, 19:16
 */

#ifndef RSAENCRIPTACION_H
#define	RSAENCRIPTACION_H

#include <string>
#include <iostream>
#include <string.h>
#include "common_md5.h"

#define CHAR_IPAD 0x36
#define CHAR_OPAD 0x5c
#define CERO_CHAR 0x00
#define TAM_CLAVE 64
#define TAM_HASH 33

class FirmaDigital {
public:
    FirmaDigital();
    
    /*
     * Aplica el algoritmo HMAC para firmar digitalmente lo que se va a enviar
     * al servidor. Antes de firmar, se debe hashear el dato a enviar utilizando
     * MD5 para obtener el digest. Luego se aplica HMAC sobre el digest con la 
     * clave que solo conocen emisor y receptor. Si el receptor al aplicar el
     * algoritmo obtiene la misma firma que fue adjuntada al mensaje original
     * se puede considerar que no hubo interferencia de terceros y que se 
     * mantuvo la integridad.
     * 
     */
    
    std::string FirmaHMAC(const char * bloque, const std::string & clave);
   
    
    ~FirmaDigital();
private:
    FirmaDigital(const FirmaDigital&);
    FirmaDigital & operator = (const FirmaDigital&);
    
    /*
     * @param clave es la clave a paddear
     * @param clave64 es la clave paddeada con ceros a la izquierda si corres-
     * ponde
     */
    void GenerarClave64Bytes(const std::string & clave,unsigned char * clave64);
    
    /*
     * Clave XOR ipad byte por byte
     */
    void XORClaveIpad(unsigned char * clave64, unsigned char * ipad);
    
    /*
     * Clave XOR opad byte por byte
     */
    void XORClaveOpad(unsigned char * clave64, unsigned char * opad);
    
    /*
     * bloque firmado = ipad + bloque para luego utilizar la función de hashing
     * MD5.
     */
    void AppendIpadBloque(unsigned char * bloque_firmado, unsigned char * ipad, 
    const char * bloque, const size_t tam_bloque_firmado);
    
    /*
     * bloque_final = opad + hash (ipad || bloque). Luego se utiliza el hash md5 
     * sobre el bloque_final resultante y dicho hash es la firma que se va a 
     * enviar al servidor.
     */
    
    void AppendOpadHash(unsigned char * bloque_final, unsigned char * opad, 
                        const char * hash);
    
    

};

#endif	/* RSAENCRIPTACION_H */

